﻿using System.Collections.Generic;
using System.Linq;

namespace Jinjia.Approve.Common.Extensions
{
    public static class DictionaryExtension
    {
        #region 给字典赋值，没有则新增

        /// <summary>
        /// key存在就修改，没有则新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> Merge<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) where TKey : notnull
        {
            if (dic != null)
            {
                if (dic.ContainsKey(key))
                {
                    dic[key] = value;
                }
                else
                {
                    dic.Add(key, value);
                }
            }

            return dic;
        }

        /// <summary>
        /// key存在就修改，没有则新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> Merge<TKey, TValue>(this Dictionary<TKey, TValue> dic, KeyValuePair<TKey, TValue> keyValue) where TKey : notnull
        {
            return dic.Merge(keyValue.Key, keyValue.Value);
        }

        /// <summary>
        /// key存在就修改，没有则新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> Merge<TKey, TValue>(this Dictionary<TKey, TValue> dic, IEnumerable<KeyValuePair<TKey, TValue>> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                foreach (var item in keyValues)
                {
                    dic.Merge(item);
                }
            }

            return dic;
        }

        /// <summary>
        /// key存在就修改，没有则新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> Merge<TKey, TValue>(this Dictionary<TKey, TValue> dic, Dictionary<TKey, TValue> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                dic.Merge(keyValues.AsEnumerable());
            }

            return dic;
        }

        #endregion

        #region key不存在时新增

        /// <summary>
        /// key不存在时新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> AddValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) where TKey : notnull
        {
            if (dic != null)
            {
                if (!dic.ContainsKey(key))
                {
                    dic.Add(key, value);
                }
            }

            return dic;
        }

        /// <summary>
        /// key不存在时新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> AddValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, KeyValuePair<TKey, TValue> keyValue) where TKey : notnull
        {
            return dic.AddValue(keyValue.Key, keyValue.Value);
        }

        /// <summary>
        /// key不存在时新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> AddValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, IEnumerable<KeyValuePair<TKey, TValue>> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                foreach (var item in keyValues)
                {
                    dic.AddValue(item);
                }
            }

            return dic;
        }

        /// <summary>
        /// key不存在时新增
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> AddValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, Dictionary<TKey, TValue> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                dic.AddValue(keyValues.AsEnumerable());
            }

            return dic;
        }

        #endregion

        #region 给字典赋值，没有则忽略

        /// <summary>
        /// 给字典赋值，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> SetValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue value) where TKey : notnull
        {
            if (dic != null)
            {
                if (dic.ContainsKey(key))
                {
                    dic[key] = value;
                }
            }

            return dic;
        }

        /// <summary>
        /// 给字典赋值，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> SetValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, KeyValuePair<TKey, TValue> keyValue) where TKey : notnull
        {
            return dic.SetValue(keyValue.Key, keyValue.Value);
        }

        /// <summary>
        /// 给字典赋值，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> SetValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, IEnumerable<KeyValuePair<TKey, TValue>> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                foreach (var item in keyValues)
                {
                    dic.SetValue(item);
                }
            }

            return dic;
        }

        /// <summary>
        /// 给字典赋值，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> SetValue<TKey, TValue>(this Dictionary<TKey, TValue> dic, Dictionary<TKey, TValue> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                dic.SetValue(keyValues.AsEnumerable());
            }

            return dic;
        }

        #endregion

        #region 删除指定key，没有则忽略

        /// <summary>
        /// 删除指定key，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> RemoveKey<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key) where TKey : notnull
        {
            if (dic != null)
            {
                dic.Remove(key);
            }

            return dic;
        }

        /// <summary>
        /// 删除指定key，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValue"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> RemoveKey<TKey, TValue>(this Dictionary<TKey, TValue> dic, KeyValuePair<TKey, TValue> keyValue) where TKey : notnull
        {
            return RemoveKey(dic, keyValue.Key);
        }

        /// <summary>
        /// 删除指定key，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> RemoveKey<TKey, TValue>(this Dictionary<TKey, TValue> dic, IEnumerable<KeyValuePair<TKey, TValue>> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                foreach (var item in keyValues)
                {
                    dic.RemoveKey(item);
                }
            }

            return dic;
        }

        /// <summary>
        /// 删除指定key，没有则忽略
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="keyValues"></param>
        /// <returns></returns>
        public static Dictionary<TKey, TValue> RemoveKey<TKey, TValue>(this Dictionary<TKey, TValue> dic, Dictionary<TKey, TValue> keyValues) where TKey : notnull
        {
            if (keyValues != null)
            {
                dic.RemoveKey(keyValues.AsEnumerable());
            }

            return dic;
        }

        #endregion

        #region 根据key查value，没有则为传过来的默认值

        /// <summary>
        /// 根据key查value，没有则为传过来的默认值
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dic"></param>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dic, TKey key, TValue defaultValue = default) where TKey : notnull
        {
            if (dic != null)
            {
                if (dic.ContainsKey(key))
                {
                    return dic[key] ?? defaultValue;
                }
            }

            return defaultValue;
        }

        #endregion
    }
}